function getNextN(n) {
  let sum = 0
  while (n) {
    sum += Math.pow(n % 10, 2)
    n = Math.floor(n / 10)
  }
  return sum
}

/**
 * 每个nextN检查是否为1或者是否已经访问过
 * @param {number} n
 * @return {boolean}
 */
export var isHappy = function (n) {
  if (n === 1) return true
  let set = new Set()
  while (n !== 1 && !set.has(n)) {
    const nextN = getNextN(n)
    if (nextN === 1) {
      return true
    }
    set.add(n)
    n = nextN
  }
  return false
}

/**
 * 快慢指针，快指针每次走两步，慢指针每次走一步
 * 最后两指针必定重合
 * @param {number} n
 * @return {boolean}
 */
export var isHappy2 = function (n) {
  if (n === 1) return true
  let slow = n,
    fast = getNextN(n)
  while (slow !== fast) {
    slow = getNextN(slow)
    fast = getNextN(getNextN(fast))
    if (slow === 1 || fast === 1) {
      return true
    }
  }
  return slow === 1
}

/**
 * 最后必定会进入 [4, 16, 37, 58, 89, 145, 42, 20, 4]的循环中或者变成1
 * 进入循环即就不快乐了
 * @param {number} n
 * @return {boolean}
 */
export var isHappy3 = function (n) {
  if (n === 1) return true
  const unHappys = [4, 16, 37, 58, 89, 145, 42, 20]
  while (n !== 1 && !unHappys.includes(n)) {
    n = getNextN(n)
    if (n === 1) return true
  }
  return false
}
